home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib43 / mntlib / bcopy.cpp < prev    next >
C/C++ Source or Header  |  1993-01-22  |  5KB  |  238 lines

  1.  
  2. |    new version of bcopy, memcpy and memmove
  3. |    handles overlap, odd/even alignment
  4. |    uses movem to copy 256 bytes blocks faster.
  5. |    Alexander Lehmann    alexlehm@iti.informatik.th-darmstadt.de
  6. |    sortof inspired by jrbs bcopy
  7.  
  8.     .text
  9.     .even
  10.     .globl _bcopy
  11.     .globl    __bcopy
  12.     .globl _memcpy
  13.     .globl _memmove
  14.  
  15. |    void *memcpy( void *dest, const void *src, size_t len );
  16. |    void *memmove( void *dest, const void *src, size_t len );
  17. |    returns dest
  18. |    functions are aliased
  19.  
  20. #ifndef __SOZOBON__
  21. _memcpy:
  22. _memmove:
  23.     movl    sp@(4),a1    | dest
  24.     movl    sp@(8),a0    | src
  25.     jra    common        | the rest is samea as bcopy
  26. #else
  27. |    _bcopy() is the base function below; for memcpy(), memmove()
  28. |    and bcopy(), we have to sneak a size_t into an unsigned long first.
  29.  
  30. _memcpy:
  31. _memmove:
  32.     movl    sp@(4),a1    | dest
  33.     movl    sp@(8),a0    | src
  34.     clrl    d0        | here is the sneaky bit...
  35.     movw    sp@(12),d0    | length
  36.     jra    common2        | the rest is samea as bcopy
  37.  
  38. _bcopy:
  39.     movl    sp@(4),a0    | src
  40.     movl    sp@(8),a1    | dest
  41.     clrl    d0        | here is the sneaky bit...
  42.     movw    sp@(12),d0    | length
  43.     jra    common2        | the rest is samea as bcopy
  44. #endif
  45.  
  46. |    void bcopy( const void *src, void *dest, size_t length );
  47. |    void _bcopy( const void *src, void *dest, unsigned long length );
  48. |    return value not used (returns src)
  49. |    functions are aliased (except for HSC -- sb)
  50.  
  51. #ifndef __SOZOBON__
  52. _bcopy:
  53. #endif
  54. __bcopy:
  55.     movl    sp@(4),a0    | src
  56.     movl    sp@(8),a1    | dest
  57. common:    movl    sp@(12),d0    | length
  58. common2:
  59.     jeq    exit        | length==0? (size_t)
  60.  
  61.                 | a0 src, a1 dest, d0.l length
  62.     movel    d2,sp@-
  63.  
  64.     | overlay ?
  65.     cmpl    a0,a1
  66.     jgt    top_down
  67.  
  68.     movw    a0,d1        | test for alignment
  69.     movw    a1,d2
  70.     eorw    d2,d1
  71.     btst    #0,d1        | one odd one even ?
  72.     jne    slow_copy
  73.     btst    #0,d2        | both even ?
  74.     jeq    both_even
  75.     movb    a0@+,a1@+    | copy one byte, now we are both even
  76.     subql    #1,d0
  77. both_even:
  78.     clrw    d1        | save length less 256
  79.     movb    d0,d1
  80.     lsrl    #8,d0        | number of 256 bytes blocks
  81.     jeq    less256
  82.     movml    d1/d3-d7/a2/a3/a5/a6,sp@-    | d2 is already saved
  83.                     | exclude a4 because of -mbaserel
  84. copy256:
  85.     movml    a0@+,d1-d7/a2/a3/a5/a6    | copy 5*44+36=256 bytes
  86.     movml    d1-d7/a2/a3/a5/a6,a1@
  87.     movml    a0@+,d1-d7/a2/a3/a5/a6
  88.     movml    d1-d7/a2/a3/a5/a6,a1@(44)
  89.     movml    a0@+,d1-d7/a2/a3/a5/a6
  90.     movml    d1-d7/a2/a3/a5/a6,a1@(88)
  91.     movml    a0@+,d1-d7/a2/a3/a5/a6
  92.     movml    d1-d7/a2/a3/a5/a6,a1@(132)
  93.     movml    a0@+,d1-d7/a2/a3/a5/a6
  94.     movml    d1-d7/a2/a3/a5/a6,a1@(176)
  95.     movml    a0@+,d1-d7/a2-a3
  96.     movml    d1-d7/a2-a3,a1@(220)
  97.     lea    a1@(256),a1        | increment dest, src is already
  98.     subql    #1,d0
  99.     jne    copy256         | next, please
  100.     movml    sp@+,d1/d3-d7/a2/a3/a5/a6
  101. less256:            | copy 16 bytes blocks
  102.     movw    d1,d0
  103.     lsrw    #2,d0        | number of 4 bytes blocks
  104.     jeq    less4        | less that 4 bytes left
  105.     movw    d0,d2
  106.     negw    d2
  107.     andw    #3,d2        | d2 = number of bytes below 16 (-n)&3
  108.     subqw    #1,d0
  109.     lsrw    #2,d0        | number of 16 bytes blocks minus 1, if d2==0
  110.     addw    d2,d2        | offset in code (movl two bytes)
  111.     jmp    pc@(2,d2:w)    | jmp into loop
  112. copy16:
  113.     movl    a0@+,a1@+
  114.     movl    a0@+,a1@+
  115.     movl    a0@+,a1@+
  116.     movl    a0@+,a1@+
  117.     dbra    d0,copy16
  118. less4:
  119.     btst    #1,d1
  120.     jeq    less2
  121.     movw    a0@+,a1@+
  122. less2:
  123.     btst    #0,d1
  124.     jeq    none
  125.     movb    a0@,a1@
  126. none:
  127. exit_d2:
  128.     movl    sp@+,d2
  129. exit:
  130.     movl sp@(4),d0        | return dest (for memcpy only)
  131.     rts
  132.  
  133. slow_copy:            | byte by bytes copy
  134.     movw    d0,d1
  135.     negw    d1
  136.     andw    #7,d1        | d1 = number of bytes blow 8 (-n)&7
  137.     addql    #7,d0
  138.     lsrl    #3,d0        | number of 8 bytes block plus 1, if d1!=0
  139.     addw    d1,d1        | offset in code (movb two bytes)
  140.     jmp    pc@(2,d1:w)    | jump into loop
  141. scopy:
  142.     movb    a0@+,a1@+
  143.     movb    a0@+,a1@+
  144.     movb    a0@+,a1@+
  145.     movb    a0@+,a1@+
  146.     movb    a0@+,a1@+
  147.     movb    a0@+,a1@+
  148.     movb    a0@+,a1@+
  149.     movb    a0@+,a1@+
  150.     subql    #1,d0
  151.     jne    scopy
  152.     jra    exit_d2
  153.  
  154. top_down:
  155.     addl    d0,a0        | a0 byte after end of src
  156.     addl    d0,a1        | a1 byte after end of dest
  157.  
  158.     movw    a0,d1        | exact the same as above, only with predec
  159.     movw    a1,d2
  160.     eorw    d2,d1
  161.     btst    #0,d1
  162.     jne    slow_copy_d
  163.  
  164.     btst    #0,d2
  165.     jeq    both_even_d
  166.     movb    a0@-,a1@-
  167.     subql    #1,d0
  168. both_even_d:
  169.     clrw    d1
  170.     movb    d0,d1
  171.     lsrl    #8,d0
  172.     jeq    less256_d
  173.     movml    d1/d3-d7/a2/a3/a5/a6,sp@-
  174. copy256_d:
  175.     movml    a0@(-44),d1-d7/a2/a3/a5/a6
  176.     movml    d1-d7/a2/a3/a5/a6,a1@-
  177.     movml    a0@(-88),d1-d7/a2/a3/a5/a6
  178.     movml    d1-d7/a2/a3/a5/a6,a1@-
  179.     movml    a0@(-132),d1-d7/a2/a3/a5/a6
  180.     movml    d1-d7/a2/a3/a5/a6,a1@-
  181.     movml    a0@(-176),d1-d7/a2/a3/a5/a6
  182.     movml    d1-d7/a2/a3/a5/a6,a1@-
  183.     movml    a0@(-220),d1-d7/a2/a3/a5/a6
  184.     movml    d1-d7/a2/a3/a5/a6,a1@-
  185.     movml    a0@(-256),d1-d7/a2-a3
  186.     movml    d1-d7/a2-a3,a1@-
  187.     lea    a0@(-256),a0
  188.     subql    #1,d0
  189.     jne    copy256_d
  190.     movml    sp@+,d1/d3-d7/a2/a3/a5/a6
  191. less256_d:
  192.     movw    d1,d0
  193.     lsrw    #2,d0
  194.     jeq    less4_d
  195.     movw    d0,d2
  196.     negw    d2
  197.     andw    #3,d2
  198.     subqw    #1,d0
  199.     lsrw    #2,d0
  200.     addw    d2,d2
  201.     jmp    pc@(2,d2:w)
  202. copy16_d:
  203.     movl    a0@-,a1@-
  204.     movl    a0@-,a1@-
  205.     movl    a0@-,a1@-
  206.     movl    a0@-,a1@-
  207.     dbra    d0,copy16_d
  208. less4_d:
  209.     btst    #1,d1
  210.     jeq    less2_d
  211.     movw    a0@-,a1@-
  212. less2_d:
  213.     btst    #0,d1
  214.     jeq    exit_d2
  215.     movb    a0@-,a1@-
  216.     jra    exit_d2
  217. slow_copy_d:
  218.     movw    d0,d1
  219.     negw    d1
  220.     andw    #7,d1
  221.     addql    #7,d0
  222.     lsrl    #3,d0
  223.     addw    d1,d1
  224.     jmp    pc@(2,d1:w)
  225. scopy_d:
  226.     movb    a0@-,a1@-
  227.     movb    a0@-,a1@-
  228.     movb    a0@-,a1@-
  229.     movb    a0@-,a1@-
  230.     movb    a0@-,a1@-
  231.     movb    a0@-,a1@-
  232.     movb    a0@-,a1@-
  233.     movb    a0@-,a1@-
  234.     subql    #1,d0
  235.     jne    scopy_d
  236.     jra    exit_d2
  237.  
  238.